package anno

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

// PackAllWithTexturePacker 遍历输入目录及子目录，批量调用 PackWithTexturePacker
// 参数：
//
//	inputRoot  -> 输入的根目录
//	outputRoot -> 输出的根目录
//	extendArgs -> 额外的参数传递给 TexturePacker
func PackAllWithTexturePacker(inputRoot, outputRoot, extendArgs string, tpsFile string) error {
	inputRoot = filepath.ToSlash(inputRoot)
	outputRoot = filepath.ToSlash(outputRoot)

	return filepath.WalkDir(inputRoot, func(path string, d os.DirEntry, err error) error {
		if err != nil {
			return err
		}

		// 只处理目录
		if !d.IsDir() {
			return nil
		}

		// 检查当前目录下是否包含 png/jpg/jpeg 文件（仅检查一层，不递归）
		hasImages := false
		entries, readErr := os.ReadDir(path)
		if readErr != nil {
			return readErr
		}
		for _, entry := range entries {
			if entry.IsDir() {
				continue
			}
			ext := strings.ToLower(filepath.Ext(entry.Name()))
			if ext == ".png" || ext == ".jpg" || ext == ".jpeg" {
				hasImages = true
				break
			}
		}

		// 如果当前目录有图片，则调用 TexturePacker
		if hasImages {
			relPath, _ := filepath.Rel(inputRoot, path)
			relPath = filepath.Dir(relPath) // 去掉最后一级目录名
			targetOutput := filepath.Join(outputRoot, relPath)

			fmt.Printf("📦 Packing %s -> %s\n", path, targetOutput)
			if err := PackWithTexturePacker(path, targetOutput, "", extendArgs, tpsFile); err != nil {
				return fmt.Errorf("failed to pack %s: %w", path, err)
			}
		}

		return nil
	})
}

// PackWithTexturePacker 使用 TexturePacker 将指定目录下的图片打包成图集
// 参数：
//
//	inputDir   -> 输入的图片文件夹
//	outputDir  -> 输出的文件夹
//	sheetName  -> 输出的图集文件名（不带扩展名, 为空则使用 inputDir 名称）
//	extendArgs -> 额外的命令参数（可选，比如 --max-width 1024 --max-height 1024）
//	tpsFile    -> 可选，TexturePacker 项目文件路径（.tps），为空则不使用
func PackWithTexturePacker(inputDir, outputDir, sheetName, extendArgs, tpsFile string) error {
	inputDir = filepath.ToSlash(inputDir)
	outputDir = filepath.ToSlash(outputDir)

	if _, err := os.Stat(inputDir); os.IsNotExist(err) {
		return fmt.Errorf("input directory does not exist: %s", inputDir)
	}

	if sheetName == "" {
		base := filepath.Base(strings.TrimRight(inputDir, string(filepath.Separator)))
		if base == "." || base == "" {
			return fmt.Errorf("invalid inputDir, cannot determine sheetName: %s", inputDir)
		}
		sheetName = base
	}

	if err := os.MkdirAll(outputDir, os.ModePerm); err != nil {
		return fmt.Errorf("failed to create output directory: %v", err)
	}

	sheetPath := filepath.ToSlash(filepath.Join(outputDir, sheetName))

	// 构造参数列表，而不是整条命令
	args := []string{}
	if tpsFile != "" {
		tpsFile = filepath.ToSlash(tpsFile)
		args = append(args, tpsFile)
	}
	args = append(args, "--format", "json")
	args = append(args, "--sheet", sheetPath+".png")
	args = append(args, "--data", sheetPath+".atlas")
	if extendArgs != "" {
		// 将 extendArgs 拆分为独立参数
		extra := strings.Fields(extendArgs)
		args = append(args, extra...)
	}
	args = append(args, inputDir)

	fmt.Printf("Running TexturePacker.exe with args:\n%v\n", args)

	cmd := exec.Command("TexturePacker.exe", args...)
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	if err := cmd.Run(); err != nil {
		return fmt.Errorf("TexturePacker failed: %v", err)
	}

	fmt.Printf("✅ Packed atlas generated at: %s.png / %s.atlas\n", sheetPath, sheetPath)
	return nil
}
